﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Pixysoft.SQL.Core
{
    class SQLStringBuilder
    {
        /// <summary>
        /// 括号的占位符
        /// </summary>
        private const string default_mark_branch = "#BRANCH#";

        Stack<KeyValuePair<string, int>> indentstack = new Stack<KeyValuePair<string, int>>();

        int stackcounter = 0;

        StringBuilder builder = new StringBuilder();


        /// <summary>
        /// 压入一个括号占位符 同时开始记录当前括号内有效的迭代次数（出现join等 就是一次迭代 因为join之前会写入一个结束括号 所以需要在开始压入一个）
        /// </summary>
        /// <returns></returns>
        public string Push()
        {
            string mark = default_mark_branch + stackcounter++;

            KeyValuePair<string, int> pair = new KeyValuePair<string, int>(mark, 0);

            indentstack.Push(pair);

            Append(mark);

            return mark;
        }

        public void Pop()
        {
            if (indentstack.Count == 0)
                return;

            KeyValuePair<string, int> pair = indentstack.Pop();

            string sql = builder.ToString();

            StringBuilder bracebuilder = new StringBuilder();

            for (int i = 0; i < pair.Value; i++)
                bracebuilder.Append(" (");

            sql = sql.Replace(pair.Key, bracebuilder.ToString());

            this.builder = new StringBuilder();

            this.builder.Append(sql);

            if (pair.Value > 0)
            {
                AppendEndBrace();
            }
        }

        public void EndUp()
        {
            while (indentstack.Count > 0)
            {
                Pop();
            }
        }

        public void Indent()
        {
            KeyValuePair<string, int> pair = indentstack.Pop();

            pair = new KeyValuePair<string, int>(pair.Key, pair.Value + 1);

            indentstack.Push(pair);
        }

        public int IndentCounter
        {
            get
            {
                if (indentstack.Count == 0)
                    return 0;

                return indentstack.Peek().Value;
            }
        }

        public void AppendEndBrace()
        {
            AppendBlank();

            Append(")");
        }




        public void AppendBlank()
        {
            builder.Append(" ");
        }

        public void Append(string value)
        {
            builder.Append(value);
        }

        public void Append(string format, params object[] values)
        {
            builder.Append(string.Format(format, values));
        }

        public void AppendLine(string value)
        {
            builder.AppendLine(value);
        }

        public void AppendLine(string format, params object[] values)
        {
            builder.AppendLine(string.Format(format, values));
        }

        public override string ToString()
        {
            return builder.ToString();
        }

        public int Length
        {
            get
            {
                return builder.Length;
            }
        }

        public void Remove(int startIndex, int length)
        {
            builder.Remove(startIndex, length);
        }
    }
}
